package io.jt808.proto.cmd;

import io.norland.buffer.AutoBuffer;
import io.norland.annotations.Proto;
import io.norland.proto.IProto;
import io.jt808.util.Tools;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 设置圆形区域
 */
@Proto("8600")
@Data
public class JT8600 implements IProto {
    /**
     * 设置属性,0：更新区域；  1：追加区域；  2：修改区域
     */
    private byte settingType;
    /**
     * 区域总数
     */
    private byte areasCount;
    /**
     * 区域项
     */
    private List<CircleAreaItem> circleAreas;

    public final byte[] writeToBytes() {
        AutoBuffer buffer = new AutoBuffer();
        buffer.writeByte(settingType);
        buffer.writeByte(areasCount);
        for (CircleAreaItem item : circleAreas) {
            buffer.writeInt(item.areaId);
            buffer.writeShort(item.areaProperty);
            buffer.writeInt((int) (item.centerLatitude * 1000000.0));
            buffer.writeInt((int) (item.centerLongitude * 1000000.0));
            buffer.writeInt(item.radius);
            if ((item.areaProperty & 1) != 0) {
                buffer.writeBcdString(getBcdDate(item.startTime), 6);
                buffer.writeBcdString(getBcdDate(item.endTime), 6);
            }
            if ((item.areaProperty & 1 << 1) != 0) {
                buffer.writeShort(item.maxSpeed);
                buffer.writeByte(item.overSpeedLastTime);
            }
        }
        return buffer.array();
    }

    private String getBcdDate(Date startTime) {
        LocalDateTime localDateTime = LocalDateTime.ofInstant(startTime.toInstant(), ZoneId.systemDefault());
        return Tools.getBcd(localDateTime.getYear() - 2000,
                localDateTime.getMonthValue(),
                localDateTime.getDayOfMonth(),
                localDateTime.getHour(),
                localDateTime.getMinute(),
                localDateTime.getSecond());
    }

    public final void readFromBuf(AutoBuffer buffer) {
        settingType = buffer.readByte();
        areasCount = buffer.readByte();
        circleAreas = new ArrayList<>();
        while (buffer.isReadable()) {
            CircleAreaItem item = new CircleAreaItem();
            item.areaId = buffer.readInt();
            item.areaProperty = buffer.readShort();
            item.centerLatitude = buffer.readInt() / 1000000.0;
            item.centerLongitude = buffer.readInt() / 1000000.0;
            item.radius = buffer.readInt();
            if ((item.areaProperty & 1) != 0) {
                item.startTime = getDate(buffer.readBcd(), buffer.readBcd(), buffer.readBcd(),
                        buffer.readBcd(), buffer.readBcd(), buffer.readBcd());
                item.endTime = getDate(buffer.readBcd(), buffer.readBcd(), buffer.readBcd(),
                        buffer.readBcd(), buffer.readBcd(), buffer.readBcd());
            }
            if ((item.areaProperty & 1 << 1) != 0) {
                item.maxSpeed = buffer.readShort();
                item.overSpeedLastTime = buffer.readUnsignedByte();
            }
            circleAreas.add(item);
        }
    }

    private Date getDate(String year1, String month1, String day1, String hour1, String minute1, String second1) {
        Integer year = Integer.valueOf(year1) + 2000;
        Integer month = Integer.valueOf(month1);
        Integer day = Integer.valueOf(day1);
        Integer hour = Integer.valueOf(hour1);
        Integer minute = Integer.valueOf(minute1);
        Integer second = Integer.valueOf(second1);
        LocalDateTime localDateTime = LocalDateTime.of(year, month, day, hour, minute, second);
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

    @Getter
    @Setter
    public class CircleAreaItem {
        /**
         * 区域ID
         */
        private int areaId;
        /**
         * 区域属性
         * 0  1：根据时间
         * 1  1：限速
         * 2  1：进区域报警给驾驶员
         * 3  1：进区域报警给平台
         * 4  1：出区域报警给驾驶员
         * 34
         * 5  1：出区域报警给平台
         * 6  0：北纬；1：南纬
         * 7  0：东经；1：西经
         * 8  0：允许开门；1：禁止开门
         * 9-13  保留
         * 14  0：进区域开启通信模块；1：进区域关闭通信模块
         * 15  0：进区域不采集 GNSS 详细定位数据；1：进区域采集 GNSS 详细定位数据
         */
        private short areaProperty;
        /**
         * 中心点纬度,以度为单位的纬度值乘以10的6次方，精确到百万分之一度
         */

        private double centerLatitude;
        /**
         * 中心点经度,以度为单位的经度值乘以10的6次方，精确到百万分之一度
         */

        private double centerLongitude;
        /**
         * 半径,单位为米（m），路段为该拐点到下一拐点
         */

        private int radius;
        /**
         * 起始时间,YY-MM-DD-hh-mm-ss，若区域属性0位为0则没有该字段
         */
        private Date startTime;
        /**
         * 结束时间,YY-MM-DD-hh-mm-ss，若区域属性0位为0则没有该字段
         */
        private Date endTime;
        /**
         * 最高速度,Km/h，若区域属性1位为0则没有该字段
         */

        private short maxSpeed;
        /**
         * 超速持续时间,单位秒(s),若区域属性1位为0则没有该字段
         */
        private short overSpeedLastTime;
    }

//    public static void main(String[] args) {
//        byte[] bytes = new byte[]{
//                0x00,
//                0x01,
//                0x00, 0x00, 0x00, 0x01,
//                (byte) 0xFF, (byte) 0xFF,
//                0x00, 0x01, (byte) 0x86, (byte) 0xa0,
//                0x00, 0x01, (byte) 0x86, (byte) 0xa0,
//                0x00, 0x00, 0x01, (byte) 0xa0,
//                0x18, 0x10, 0x26, 0x17, 0x15, 0x13,
//                0x18, 0x10, 0x30, 0x17, 0x15, 0x13,
//                (byte) 0xa0, 0x00,
//                (byte) 0xa0
//        };
//        JT8600 jt8600 = new JT8600();
//        jt8600.readFromBuf(new AutoBuffer(bytes));
//        System.out.println(new String(bytes).equals(new String(jt8600.writeToBytes())));
//    }
}